<template>
    <div class="video-uploader">
      <div v-if="existingVideo" class="preview-box">
        <video :src="existingVideo" controls class="video-player"></video>
        <div class="action-bar">
          <el-button type="primary" plain size="small" @click="handleReupload">
            <i class="el-icon-refresh-right"></i> 重新上传
          </el-button>
        </div>
      </div>
      <el-upload
        v-else
        class="uploader-box"
        ref="upload"
        :action="uploadUrl"
        :headers="headers"
        :on-progress="handleProgress"
        :on-success="handleSuccess"
        :on-error="handleError"
        :before-upload="beforeUpload"
        :show-file-list="false"
        drag
      >
        <div class="upload-area">
          <i class="el-icon-upload"></i>
          <div class="upload-tip">点击或拖拽上传视频</div>
          <div class="upload-desc">支持 mp4、avi、mov 格式</div>
        </div>
      </el-upload>
      <transition name="fade">
        <div v-if="uploadProgress > 0" class="progress-box">
          <el-progress
            :percentage="uploadProgress"
            :show-text="false"
            :stroke-width="4"
          ></el-progress>
          <span class="progress-text">{{ uploadProgress }}%</span>
        </div>
      </transition>
    </div>
</template>

<script>
export default {
  props: {
    existingVideo: {
      type: String,
      default: ''
    }
  },
  data () {
    return {
      uploadUrl: process.env.VUE_APP_BASE_API + '/api/upload',
      headers: {
        token: localStorage.getItem('token')
      },
      uploadProgress: 0
    }
  },
  methods: {
    handleReupload () {
      this.$emit('update:existingVideo', '')
    },
    beforeUpload (file) {
      const isVideo = file.type === 'video/mp4' || file.type === 'video/avi' || file.type === 'video/mov'
      if (!isVideo) {
        this.$message.error('请上传正确的视频格式文件')
        return false
      }
      const isLt500M = file.size / 1024 / 1024 < 500
      if (!isLt500M) {
        this.$message.error('视频大小不能超过 500MB')
        return false
      }
      return true
    },
    handleProgress (event) {
      try {
        this.uploadProgress = Math.round((event.loaded / event.total) * 100)
      } catch (error) {
        this.$message.error('上传出现异常')
        this.uploadProgress = 0
      }
    },
    handleSuccess (response) {
      if (response.code === 1) {
        this.$message.success('上传成功')
        const videoUrl = response.data.startsWith('http')
          ? response.data
          : process.env.VUE_APP_BASE_API + response.data
        this.$emit('getUrl', videoUrl)
        this.$emit('update:existingVideo', videoUrl)
      } else {
        this.handleError()
      }
      this.uploadProgress = 0
    },
    handleError () {
      this.$message.error('上传失败，请重试')
      this.uploadProgress = 0
    }
  }
}
</script>

<style scoped>
.video-uploader {
  width: 100%;
  border-radius: 4px;
  background: #fff;
}

.uploader-box {
  width: 100%;
}

.upload-area {
  padding: 30px 0;
  text-align: center;
}

.el-icon-upload {
  font-size: 40px;
  color: #909399;
  margin-bottom: 12px;
}

.upload-tip {
  font-size: 15px;
  color: #606266;
  margin-bottom: 6px;
}

.upload-desc {
  font-size: 13px;
  color: #909399;
}

:deep(.el-upload-dragger) {
  width: 100%;
  border: 1px dashed #d9d9d9;
  border-radius: 4px;
  background-color: #fff;
  transition: all 0.3s;
}

:deep(.el-upload-dragger:hover) {
  border-color: #409EFF;
  background-color: #fff;
}

.preview-box {
  width: 100%;
  background: #fff;
  border-radius: 4px;
  overflow: hidden;
}

.video-player {
  width: 100%;
  display: block;
  background: #000;
}

.action-bar {
  padding: 12px;
  text-align: center;
  background: #f8f9fa;
}

.progress-box {
  margin-top: 12px;
  padding: 0 2px;
  display: flex;
  align-items: center;
  gap: 10px;
}

.progress-text {
  min-width: 45px;
  font-size: 13px;
  color: #409EFF;
}

:deep(.el-progress-bar__outer) {
  background-color: #f0f2f5;
}

:deep(.el-progress-bar__inner) {
  transition: width 0.3s ease;
}

.fade-enter-active, .fade-leave-active {
  transition: opacity 0.3s;
}

.fade-enter, .fade-leave-to {
  opacity: 0;
}
</style>
